﻿#ifndef __SS_MAP_H__
#define __SS_MAP_H__
#include "rbTree/ssRBTree.h"
#include "ssPair.h"

namespace StarSeeker
{

template<typename MAP_FIRST, typename MAP_SECOND, typename MAP_POOL=ssDefMallocObject<ssRBTreeNode<ssPair<MAP_FIRST,MAP_SECOND> > > >
class ssMap
{
public:
	class Iterator
	{
		friend class ssMap;
	public:
		Iterator() :m_pNode(0)
		{
		}
		Iterator(const Iterator & it) :m_pNode(it.m_pNode)
		{
		}
		Iterator(ssRBTreeNode<ssPair<MAP_FIRST,MAP_SECOND> >* p) :m_pNode(p)
		{
		}
		bool operator == (const Iterator& it) const
		{
			return this->m_pNode == it.m_pNode;
		}
		bool operator != (const Iterator& it) const
		{
			return this->m_pNode != it.m_pNode;
		}
		void operator = (const Iterator & it)
		{
			this->m_pNode = it.m_pNode;
		}
		void operator ++ ()
		{
			ssRBTree<ssPair<MAP_FIRST, MAP_SECOND>, MAP_POOL>* pTree = (ssRBTree<ssPair<MAP_FIRST, MAP_SECOND>, MAP_POOL>*)m_pNode->Onwer();
			m_pNode = pTree->Next();
		}
		const MAP_FIRST& First()
		{
			return m_pNode->GetKey().first;
		}
		MAP_SECOND& Second()
		{
			return SS_CONST_CAST(MAP_SECOND&, m_pNode->GetKey().second);
		}
		bool IsVaild() const
		{
			if (!m_pNode)
			{
				return false;
			}
			if (0 == m_pNode->Onwer())
			{
				return false;
			}
			return true;
		}
	private:
		ssRBTreeNode<ssPair<MAP_FIRST,MAP_SECOND> >*	m_pNode;
	};

	ssMap();
	ssPair<Iterator, error_t>	Insert(const MAP_FIRST& f, const MAP_SECOND& s);
	ssPair<Iterator, error_t>	InsertCover(const MAP_FIRST& f, const MAP_SECOND& s);
	Iterator		Find(const MAP_FIRST& f);
	error_t			Erase(Iterator& itr);
	error_t			Erase(const MAP_FIRST& f);
	Iterator		Begin();
	Iterator		End();
	void			Empty();
	ulint			Size();
	bool			Check();
	MAP_SECOND& operator[] (const MAP_FIRST& f);
	error_t			Error();
private:
	ssRBTree<ssPair<MAP_FIRST,MAP_SECOND>,MAP_POOL>	m_tree;
	error_t											m_errno;
};

template<typename MAP_FIRST, typename MAP_SECOND, typename MAP_POOL>
ssMap<MAP_FIRST, MAP_SECOND, MAP_POOL>::ssMap()
{
	m_errno = 0;
}

template<typename MAP_FIRST,typename MAP_SECOND,typename MAP_POOL>
inline ssPair<typename ssMap<MAP_FIRST, MAP_SECOND, MAP_POOL>::Iterator, error_t> ssMap<MAP_FIRST,MAP_SECOND,MAP_POOL>::Insert(const MAP_FIRST& f, const MAP_SECOND& s)
{
	ssPair<MAP_FIRST,MAP_SECOND> node(f, s);
	ssPair<ssRBTreeNode<ssPair<MAP_FIRST, MAP_SECOND> >*, error_t> ret = m_tree.Insert(node);
	m_errno = ret.second;
	return ssPair<ssMap<MAP_FIRST, MAP_SECOND, MAP_POOL>::Iterator, error_t>(ret.first, ret.second);
}

template<typename MAP_FIRST,typename MAP_SECOND,typename MAP_POOL>
inline ssPair<typename ssMap<MAP_FIRST, MAP_SECOND, MAP_POOL>::Iterator, error_t> ssMap<MAP_FIRST,MAP_SECOND,MAP_POOL>::InsertCover(const MAP_FIRST& f, const MAP_SECOND& s)
{
	ssPair<MAP_FIRST, MAP_SECOND> node(f, s);
	ssPair<ssRBTreeNode<ssPair<MAP_FIRST, MAP_SECOND> >*, error_t> ret = m_tree.Insert(node);
	m_errno = ret.second;
	if (m_errno==SS_RBT_KEY_EXISTED)
	{
		SS_CONST_CAST(MAP_SECOND&, ret.first->GetKey().second) = s;
	}
	return ssPair<ssMap<MAP_FIRST, MAP_SECOND, MAP_POOL>::Iterator, error_t>(ret.first, ret.second);
}

template<typename MAP_FIRST,typename MAP_SECOND,typename MAP_POOL>
inline typename ssMap<MAP_FIRST,MAP_SECOND,MAP_POOL>::Iterator ssMap<MAP_FIRST,MAP_SECOND,MAP_POOL>::Find(const MAP_FIRST& f)
{
	ssPair<MAP_FIRST,MAP_SECOND> node(f);
	ssRBTreeNode<ssPair<MAP_FIRST,MAP_SECOND> >* ret = m_tree.Find(node);
	return ret;
}

template<typename MAP_FIRST,typename MAP_SECOND,typename MAP_POOL>
inline error_t ssMap<MAP_FIRST,MAP_SECOND,MAP_POOL>::Erase(Iterator& itr)
{
	m_errno = m_tree.Remove(itr.m_pNode);
	return m_errno;
}

template<typename MAP_FIRST,typename MAP_SECOND,typename MAP_POOL>
inline error_t ssMap<MAP_FIRST,MAP_SECOND,MAP_POOL>::Erase(const MAP_FIRST& f)
{
	ssPair<MAP_FIRST,MAP_SECOND> node(f);
	m_errno = m_tree.Remove(node);
	return m_errno;
}

template<typename MAP_FIRST,typename MAP_SECOND,typename MAP_POOL>
inline typename ssMap<MAP_FIRST,MAP_SECOND,MAP_POOL>::Iterator ssMap<MAP_FIRST,MAP_SECOND,MAP_POOL>::Begin()
{
	return m_tree.Begin();
}

template<typename MAP_FIRST,typename MAP_SECOND,typename MAP_POOL>
inline typename ssMap<MAP_FIRST,MAP_SECOND,MAP_POOL>::Iterator ssMap<MAP_FIRST,MAP_SECOND,MAP_POOL>::End()
{
	return m_tree.End();
}

template<typename MAP_FIRST,typename MAP_SECOND,typename MAP_POOL>
inline void ssMap<MAP_FIRST,MAP_SECOND,MAP_POOL>::Empty()
{
	m_tree.Empty();
}

template<typename MAP_FIRST,typename MAP_SECOND,typename MAP_POOL>
inline ulint ssMap<MAP_FIRST,MAP_SECOND,MAP_POOL>::Size()
{
	return m_tree.GetCount();
}

template<typename MAP_FIRST,typename MAP_SECOND,typename MAP_POOL>
inline bool ssMap<MAP_FIRST,MAP_SECOND,MAP_POOL>::Check()
{
	return m_tree.Check();
}

template<typename MAP_FIRST,typename MAP_SECOND,typename MAP_POOL>
MAP_SECOND& StarSeeker::ssMap<MAP_FIRST,MAP_SECOND,MAP_POOL>::operator[](const MAP_FIRST& f)
{
	ssPair<MAP_FIRST, MAP_SECOND> node(f);
	ssPair<ssRBTreeNode<ssPair<MAP_FIRST, MAP_SECOND> >*, error_t> ret = m_tree.Insert(node);
	m_errno = ret.second;
	return SS_CONST_CAST(MAP_SECOND&, ret.first->GetKey().second);
}

template<typename MAP_FIRST, typename MAP_SECOND, typename MAP_POOL>
error_t StarSeeker::ssMap<MAP_FIRST, MAP_SECOND, MAP_POOL>::Error()
{
	return m_errno;
}

#define SS_MAP_O(MAP_FIRST,MAP_SECOND) StarSeeker::ssMap<MAP_FIRST, MAP_SECOND, StarSeeker::ssMallocObj<StarSeeker::ssRBTreeNode<StarSeeker::ssPair<MAP_FIRST,MAP_SECOND> > > >
#define SS_MAP_N(MAP_FIRST,MAP_SECOND) StarSeeker::ssMap<MAP_FIRST, MAP_SECOND, StarSeeker::ssMalloc<sizeof(StarSeeker::ssRBTreeNode<StarSeeker::ssPair<MAP_FIRST,MAP_SECOND> >) > >
}
#endif
